package com.myk.game.gobangchess.rooms.oldrooms;

import com.myk.game.gobangchess.CustomBottom;
import com.myk.game.gobangchess.Player;
import com.myk.game.gobangchess.constants.BoardStyleData;
import com.myk.game.gobangchess.constants.WinMode;
import com.myk.game.gobangchess.utils.GridsUtils;
import com.myk.game.gobangchess.Room;

/**
 * 超能四子棋房间
 */
public class SuperenergyGoBangRoom extends Room {

    private boolean isRotate;//是否为旋转状态的按钮

    public SuperenergyGoBangRoom(String roomName) {
        super(roomName, "\t\t星影开发的四子棋，可使用技能点释放技能达成四连", "超能四子棋", BoardStyleData.getGoBangStyle(16, 16),true,false);
    }

    @Override
    public String getRuleText() {
        return "黑白双方轮流落子。\n" +
                "获胜条件：形成四子一线4次\n" +
                "和棋条件：无棋可走";
    }

    @Override
    public void doRule(int row, int col, int value) {
        if (curGrids[row][col] == 0) { //只能落在空位置

            curGrids[row][col] = value; //实际落子
            //黑方落子时
            WinState winState = checkWin(row, col);
            if (winState != null) {
                doOver(winState.winMode, winState.winMsg);
            } else {
                noticeChangeMove();
            }

        }
    }



    private void noticeChangeMove(){
        stepAdd();;
        if (cur == 1) {
            noticeWhiteMove();
        } else if (cur == 2) {
            noticeBlackMove();
        }
    }
    /**
     * 顺势
     */
    private boolean rotateClockwise(int row, int col) {
        // 计算矩形区域的边界
        int startRow = Math.max(0, row - 1);
        int endRow = Math.min(curGrids.length - 1, row + 1);
        int startCol = Math.max(0, col - 1);
        int endCol = Math.min(curGrids[0].length - 1, col + 1);

        // 检查边界条件
        if (startRow >= endRow || startCol >= endCol) {
            return false;
        }

        // 创建临时数组存储旋转后的值
        int[][] temp = new int[3][3];

        // 复制旋转前的值到临时数组
        for (int i = startRow; i <= endRow; i++) {
            for (int j = startCol; j <= endCol; j++) {
                temp[i - startRow][j - startCol] = curGrids[i][j];
            }
        }

        // 旋转
        curGrids[row - 1][col] = temp[2][0];
        curGrids[row][col + 1] = temp[0][0];
        curGrids[row + 1][col] = temp[0][2];
        curGrids[row][col - 1] = temp[2][2];
        curGrids[row - 1][col + 1] = temp[1][0];
        curGrids[row + 1][col + 1] = temp[0][1];
        curGrids[row - 1][col - 1] = temp[2][1];
        curGrids[row + 1][col - 1] = temp[1][2];

        return true;
    }

    /**
     * 逆势
     */
    private boolean rotateCounterClockwise(int row, int col) {
        // 计算矩形区域的边界
        int startRow = Math.max(0, row - 1);
        int endRow = Math.min(curGrids.length - 1, row + 1);
        int startCol = Math.max(0, col - 1);
        int endCol = Math.min(curGrids[0].length - 1, col + 1);

        // 检查边界条件
        if (startRow >= endRow || startCol >= endCol) {
            return false;
        }

        // 创建临时数组存储旋转后的值
        int[][] temp = new int[3][3];

        // 复制旋转前的值到临时数组
        for (int i = startRow; i <= endRow; i++) {
            for (int j = startCol; j <= endCol; j++) {
                temp[i - startRow][j - startCol] = curGrids[i][j];
            }
        }

        // 旋转
        curGrids[row - 1][col] = temp[0][2];
        curGrids[row][col + 1] = temp[2][2];
        curGrids[row + 1][col] = temp[2][0];
        curGrids[row][col - 1] = temp[0][0];
        curGrids[row - 1][col + 1] = temp[1][2];
        curGrids[row + 1][col + 1] = temp[2][1];
        curGrids[row - 1][col - 1] = temp[0][1];
        curGrids[row + 1][col - 1] = temp[1][0];

        return true;
    }

    /**
     * 黑白逆转
     */
    private void reverseBlackAndWhite() {
        for (int i = 0; i < curGrids.length; i++) {
            for (int j = 0; j < curGrids[i].length; j++) {
                if (curGrids[i][j] == 1) {
                    curGrids[i][j] = 2;
                } else if (curGrids[i][j] == 2) {
                    curGrids[i][j] = 1;
                }
            }
        }
    }

    //获取成5的次数
    private WinState checkWin(int row, int col) {
        int winValue = 0;
        int[][] dxdy = {{1, 0}, {-1, 1}, {0, 1}, {1, 1}};
        for (int i = 0; i < dxdy.length; i++) {
            int dx = dxdy[i][0], dy = dxdy[i][1];
            int length = getJudgeLength(row, col, dx, dy) + getJudgeLength(row, col, -dx, -dy) - 1;
            if (length >= 4) {
                winValue = (curGrids[row][col] + 1) % 2 + 1;
            }
        }

        boolean gridFull = GridsUtils.getDataCount(curGrids, 0) == 0;

        if (winValue == 1) {
            return new WinState(WinMode.BLACK_WIN, player_black.getNickNameOrTemp() + "执黑棋战胜" + player_white.getNickNameOrTemp());
        } else if (winValue == 2) {
            return new WinState(WinMode.WHITE_WIN, player_white.getNickNameOrTemp() + "执白棋战胜" + player_black.getNickNameOrTemp());
        } else if (gridFull) {
            return new WinState(WinMode.BOTH_DRAW, player_black.getNickNameOrTemp() + "-黑棋战平" + player_white.getNickNameOrTemp() + "-白棋");
        } else {
            return null;
        }
    }

    private int getJudgeLength(int x, int y, int dx, int dy) {
        int value = curGrids[x][y];
        int length = 0;
        while (isInGrids(x, y)) {
            if (curGrids[x][y] != value) {
                return length;
            }
            length++;
            x += dx;
            y += dy;
        }
        return length;
    }

    private boolean isInGrids(int row, int col) {
        return row >= 0 && row <= curGrids.length - 1 && col >= 0 && col <= curGrids[0].length - 1;
    }

    @Override
    public void noticeBlackMove() {
        blackBottoms();
        super.noticeBlackMove();
    }

    private void blackBottoms() {
        if (player_black != null) {
            if (!isRotate) {
                player_black.clearCustomBottom();
                player_black.dispatchCustomBottom();
                player_black.registerCustomBottom(new CustomBottom(this, "黑白逆转", (player) -> {
                    noticeBlackMove();
                }));
                player_black.registerCustomBottom(new CustomBottom(this, "铁索", (player) -> {
                    noticeBlackMove();
                }));
                player_black.registerCustomBottom(new CustomBottom(this, "解锁", (player) -> {
                    noticeBlackMove();
                }));
                player_black.registerCustomBottom(new CustomBottom(this, "旋转", (player) -> {
                    isRotate = true;
                    noticeBlackMove();
                }));
            } else {
                player_black.clearCustomBottom();
                player_black.dispatchCustomBottom();
                player_black.registerCustomBottom(new CustomBottom(this, "顺势", (player) -> {
//                    isRotate = true;
                    noticeBlackMove();
                }));
                player_black.registerCustomBottom(new CustomBottom(this, "逆势", (player) -> {
//                    isRotate = true;
                    noticeBlackMove();
                }));
                player_black.registerCustomBottom(new CustomBottom(this, "返回", (player) -> {
                    isRotate = false;
                    noticeBlackMove();
                }));
            }
        }
        if (player_white != null) {
            player_white.clearCustomBottom();
            player_white.dispatchCustomBottom();
        }
    }

    @Override
    public void noticeWhiteMove() {
        whiteBottoms();
        super.noticeWhiteMove();
    }

    private void whiteBottoms() {
        if (player_white != null) {
            if (!isRotate) {
                player_white.clearCustomBottom();
                player_white.dispatchCustomBottom();
                player_white.registerCustomBottom(new CustomBottom(this, "黑白逆转", (player) -> {
                    noticeWhiteMove();
                }));
                player_white.registerCustomBottom(new CustomBottom(this, "铁索", (player) -> {
                    noticeWhiteMove();
                }));
                player_white.registerCustomBottom(new CustomBottom(this, "解锁", (player) -> {
                    noticeWhiteMove();
                }));
                player_white.registerCustomBottom(new CustomBottom(this, "旋转", (player) -> {
                    isRotate = true;
                    noticeWhiteMove();
                }));
            } else {
                player_white.clearCustomBottom();
                player_white.dispatchCustomBottom();
                player_white.registerCustomBottom(new CustomBottom(this, "顺势", (player) -> {
//            isRotate = true;
                    noticeWhiteMove();
                }));
                player_white.registerCustomBottom(new CustomBottom(this, "逆势", (player) -> {
//            isRotate = true;
                    noticeWhiteMove();
                }));
                player_white.registerCustomBottom(new CustomBottom(this, "返回", (player) -> {
                    isRotate = false;
                    noticeWhiteMove();
                }));
            }
        }
        if (player_black != null) {
            player_black.clearCustomBottom();
            player_black.dispatchCustomBottom();
        }
    }

    @Override
    public void noticeOnSeatReConnectMove(Player player) {
        super.noticeOnSeatReConnectMove(player);
        if (cur == 1){
            blackBottoms();
        }
        else if (cur == 2){
            whiteBottoms();
        }
    }

    public static class WinState {
        public int winMode;
        public String winMsg;

        public WinState(int winMode, String winMsg) {
            this.winMode = winMode;
            this.winMsg = winMsg;
        }

    }
}
